package org.jsets.fastboot.persistent.config;

import org.jsets.fastboot.persistent.IDesensitizeService;
import org.jsets.fastboot.persistent.IEncryptService;
import org.jsets.fastboot.util.SpringContextHolder;
import org.jsets.fastboot.util.StringUtils;
import org.jsets.fastboot.persistent.impl.DesensitizeService;
import org.jsets.fastboot.persistent.impl.EncryptService;
import org.jsets.fastboot.persistent.impl.JaversService;
import org.jsets.fastboot.persistent.interceptor.ExecutorInterceptor;
import org.jsets.fastboot.persistent.interceptor.ResultSetHandlerInterceptor;
import org.jsets.fastboot.persistent.interceptor.StatementHandlerInterceptor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

@Configuration
@EnableConfigurationProperties(PersistentProperties.class)
public class PersistentAutoConfiguration implements InitializingBean {

	@Autowired
	private ApplicationContext applicationContext;

	@Autowired
	private Environment environment;

	@Override
	public void afterPropertiesSet() throws Exception {
		SpringContextHolder.setApplicationContextIfNecessary(applicationContext);
		SpringContextHolder.setEnvironmentIfNecessary(environment);
		String typeAliasesPackage = SpringContextHolder.getProperty(MybatisPlusProperties.PREFIX+".type-aliases-package", "");
		if(!StringUtils.isBlank(typeAliasesPackage)) {
			PersistentAnnotationResolver.resolveEntityPackage(typeAliasesPackage);
		}
		String typeMapperPackage = SpringContextHolder.getProperty(PersistentProperties.PREFIX+".type-mapper-package", "");
		if(!StringUtils.isBlank(typeMapperPackage)) {
			PersistentAnnotationResolver.resolveMapperPackage(typeMapperPackage);
		}
	}

	@Bean
	@ConditionalOnMissingBean
	public IEncryptService encryptService(PersistentProperties properties) {
		return new EncryptService(properties);
	}

	@Bean
	@ConditionalOnMissingBean
	public IDesensitizeService desensitizeService() {
		return new DesensitizeService();
	}

	@Bean
	public ExecutorInterceptor executorInterceptor(PersistentProperties properties) {
		return new ExecutorInterceptor(properties.isTimeConsuming());
	}

	@Bean
	public StatementHandlerInterceptor statementHandlerInterceptor() {
		return new StatementHandlerInterceptor();
	}

	@Bean
	public ResultSetHandlerInterceptor resultSetHandlerInterceptor() {
		return new ResultSetHandlerInterceptor();
	}

	@Bean
	@ConditionalOnMissingBean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
		interceptor.addInnerInterceptor(paginationInnerInterceptor);
		return interceptor;
	}

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnProperty(prefix = JaversProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = false)
	public JaversService javersService(PersistentProperties properties) {
		JaversService javersService = new JaversService(properties);
		javersService.afterInitialize();
		return javersService;
	}

}